package com.roamer.audition.web.security;

import com.roamer.audition.web.security.filter.JwtAuthenticationFilter;
import com.roamer.audition.web.security.handler.AuthFailureHandler;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutFilter;

/**
 * username安全配置
 *
 * @author roamer
 * @version v1.0
 * @date 2020/3/9 15:42
 */
public class JwtValidConfigurer<T extends JwtValidConfigurer<T, B>, B extends HttpSecurityBuilder<B>> extends AbstractHttpConfigurer<T, B> {

    private final JwtAuthenticationFilter authenticationProcessingFilter;

    public JwtValidConfigurer() {
        authenticationProcessingFilter = new JwtAuthenticationFilter();
    }

    @Override
    public void configure(B httpBuilder) throws Exception {
        // 设置Filter使用的AuthenticationManager
        authenticationProcessingFilter.setAuthenticationManager(httpBuilder.getSharedObject(AuthenticationManager.class));
        // 设置失败的Handler
        authenticationProcessingFilter.setAuthenticationFailureHandler(new AuthFailureHandler());
        JwtAuthenticationFilter filter = postProcess(authenticationProcessingFilter);
        //指定Filter的位置
        httpBuilder.addFilterAfter(filter, LogoutFilter.class);
        super.configure(httpBuilder);
    }

    /**
     * 设置匿名用户可访问url
     *
     * @param urls 忽视的url
     * @return {@code JwtSecurityConfig<T, B>}
     */
    public JwtValidConfigurer<T, B> permissiveRequestUrls(String... urls) {
        authenticationProcessingFilter.setPermissiveUrl(urls);
        return this;
    }

    /**
     * 设置成功的Handler，这个handler定义成Bean，所以从外面set进来
     *
     * @param authSuccessHandler 认证成功处理器
     * @return {@code SecurityConfig} 安全配置
     */
    public JwtValidConfigurer<T, B> tokenValidSuccessHandler(AuthenticationSuccessHandler authSuccessHandler) {
        authenticationProcessingFilter.setAuthenticationSuccessHandler(authSuccessHandler);
        return this;
    }


}
